package com.sunfeng.n8.concurrenthashmap;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author sunfeng
 * @date 2021/04/22 17:37
 **/
public class Test2 {

    public static int number = 26;

    public static void main(String[] args) {
        demo(
                (Supplier<Map<String, LongAdder>>) ConcurrentHashMap::new,
                //     (Supplier<Map<String, Integer>>) HashMap::new,
                (map, words) -> {
                    for (String word : words) {
//                        Integer counter = map.get(word);
//                        int newValue = counter == null ? 1 : counter + 1;
//                        map.put(word, newValue);
                        LongAdder value = map.computeIfAbsent(word, s -> new LongAdder());
                        value.increment();
                    }
                }
        );
    }

    private static <V> void demo(Supplier<Map<String, V>> supplier,
                                 BiConsumer<Map<String, V>, List<String>> consumer) {
        // 从supplier 中获取
        Map<String, V> counterMap = supplier.get();
        List<Thread> ts = new ArrayList<>();
        // 遍历26次数据
        for (int i = 1; i <= number; i++) {      
            int idx = i;
            Thread thread = new Thread(() -> {
                List<String> words = readFromFile(idx);
                consumer.accept(counterMap, words);
            });
            ts.add(thread);
        }
        ts.forEach(Thread::start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(counterMap);
    }

    public static List<String> readFromFile(int i) {
        ArrayList<String> words = new ArrayList<>();
        try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("F:\\03_study\\concurrent\\tmp\\" + i + ".txt")))) {
            while (true) {
                String word = in.readLine();
                if (word == null) {
                    break;
                }
                words.add(word);
            }
            return words;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
